package netWork.练习1_聊天室.多客户端实现;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.List;

/**
 * @Package netWork.练习1_聊天室.多客户端实现
 * @Author shimmer
 * @Date 2020/8/4 8:15
 * @TODO 服务器相当于一个广播平台，只负责将收到的信息发给每个人
 */
public class Server {
    // 客户数组
    List<Socket> clientList;
    String data;
    private DataOutputStream os;
    private DataInputStream is;
    ServerSocket serverSocket;

    public Server() {
        clientList = new ArrayList<>();
        try {
            serverSocket = new ServerSocket(8888);
            // 持续监听客户端请求
            while (true) {
                Socket client = serverSocket.accept();
                clientList.add(client);// 加入列表
                // 为每一个用户开启服务一条服务线程
                new serverThread(client).start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 服务线程
    class serverThread extends Thread {
        Socket client;

        public serverThread(Socket client) {
            this.client = client;
        }
        
        @Override
        public void run() {
            try {
                data = "欢迎【" + client.getPort() + "】进入聊天室！当前聊天室有【"
                        + clientList.size() + "】人";
                sendData(data);// 发送欢迎
                is = new DataInputStream(client.getInputStream());
                /* 注意：is.readUTF()方法返回值要用变量接收 */
                while (true) {
                    data = is.readUTF();// 阻塞读取
                    if (!"q".equals(data)){
                        data = "【" + client.getPort() + "】说：" + data;
                        System.out.println(data);
                        sendData(data);
                    }else { 
                        clientList.remove(client);// 移除列表
                        data = "【" + client.getPort() + "】：退出聊天室";;
                        sendData(data); 
                        break;
                    }
                }
            } catch (SocketException e){ // 捕获客户端连接中断
                clientList.remove(client);// 移除列表
                data = "【" + client.getPort() + "】：退出聊天室";;
                sendData(data);
            } catch (IOException e) {
                e.printStackTrace();
            } finally{
                new CloseUtil(client).close();
            }
        }
    }

    // 发送数据
    private void sendData(String data) {
        try {
            for (Socket client : clientList) {
                os = new DataOutputStream(client.getOutputStream());
                os.writeUTF(data);
                os.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        new Server();
    }
}
